package io.gitee.zhangbinhub.acp.cloud.oauth.controller;

import io.gitee.zhangbinhub.acp.boot.exceptions.WebException;
import io.gitee.zhangbinhub.acp.cloud.tools.CloudTools;
import io.gitee.zhangbinhub.acp.core.common.CommonTools;
import org.bouncycastle.util.encoders.Base64;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClient;

import java.nio.charset.Charset;

@RestController
@RequestMapping
public class TokenController {
    @Value("${spring.application.name}")
    private String serverName;
    private final CloudTools cloudTools;
    private final RestClient.Builder restClientBuilder;

    public TokenController(CloudTools cloudTools,
                           @Qualifier("acpSpringCloudResourceServerRestClientBuilder")
                           RestClient.Builder restClientBuilder) {
        this.cloudTools = cloudTools;
        this.restClientBuilder = restClientBuilder;
    }

    @PostMapping(value = "/oauth/token", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> token(@RequestParam MultiValueMap<String, Object> paramMap) {
        try {
            return restClientBuilder.build().post().uri("http://" + serverName + "/inner/oauth/token")
                    .accept(MediaType.APPLICATION_JSON)
                    .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                    .headers(headers -> {
                        cloudTools.transmitHeadersServlet(headers, null, false);
                        headers.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64.toBase64String((paramMap.getFirst("client_id") + ":" + paramMap.getFirst("client_secret")).getBytes(Charset.forName(CommonTools.getDefaultCharsetName()))));
                    })
                    .body(paramMap)
                    .retrieve()
                    .toEntity(String.class);
        } catch (HttpClientErrorException e) {
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            throw new WebException(HttpStatus.UNAUTHORIZED, e.getMessage());
        }
    }

}
